package com.jz.netthings.utils;


import lombok.Data;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

@Data
public class DateUnit {
    private static final String TimeIdShort1FormatString = "yyMM";
    private static final String TimeIdShortFormatString = "yyMMdd";
    private static final String TimeIdFormatString = "yyyyMMdd";
    private static final String ShortDate1FormatString = "yy-MM";
    private static final String ShortDate2FormatString = "yyyy-MM";
    private static final String ShortDateFormatString = "yy-MM-dd";
    private static final String ShortDateFormatString1 = "yyyy-M-d";
    private static final String NormalDateFormatString = "yyyy-MM-dd";
    private static final String NormalDateFormatString1 = "yyyy-MM-dd HH:mm";
    private static final String LongDateTimeFormatString = "yyyy-MM-dd HH:mm:ss";
    private static final String RealDateTimeFormatString = "yyyy-MM-dd HH:mm:ss:SSS";
    private static final String ShortDateFormatString2 = "MM-dd HH:mm";
    private static final String ShortDateFormatCNString1 = "yy年MM月dd日";
    private static final String ShortDateFormatCNString = "yyyy年MM月dd日";
    private static final String NormalDateFormatCNString = "yyyy年MM月dd日 HH:mm";
    private static final String LongDateTimeFormatCNString = "yyyy年MM月dd日 HH:mm:ss";
    private static final String RealDateTimeFormatCNString = "yyyy年MM月dd日 HH:mm:ss:SSS";
    private static final String YearDateFormatCNString1 = "yyyy";
    private static final String YearDateFormatCNString2 = "yyyy";
    private static final String MonthDateFormatCNString1 = "yyyy-MM";
    private static final String TimeFormatString = "HH:mm:ss";
    private static final String TimeFormat1String = "HHmmss";
    private static final String TimeFormat2String = "HH-mm-ss";
    private static final String TimeSerialFormatString = "yyyyMMddHHmmssSSS";
    private static final String JsonDateFormatString1 = "yyyy/MM/dd HH:mm:ss";
    private static SimpleDateFormat TimeIdShortFormat = new SimpleDateFormat("yyMMdd");
    private static SimpleDateFormat TimeIdFormat = new SimpleDateFormat("yyyyMMdd");
    private static SimpleDateFormat ShortDateFormat = new SimpleDateFormat("yy-MM-dd");
    private static SimpleDateFormat ShortDateFormat1 = new SimpleDateFormat("yyyy-M-d");
    private static SimpleDateFormat ShortDateFormat2 = new SimpleDateFormat("MM-dd HH:mm");
    private static SimpleDateFormat NormalDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    private static SimpleDateFormat NormalDateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
    private static SimpleDateFormat LongDateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private static SimpleDateFormat RealDateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
    private static SimpleDateFormat ShortDateFormatCN1 = new SimpleDateFormat("yy年MM月dd日");
    private static SimpleDateFormat ShortDateCNFormat = new SimpleDateFormat("yyyy年MM月dd日");
    private static SimpleDateFormat NormalDateCNFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm");
    private static SimpleDateFormat LongDateCNFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
    private static SimpleDateFormat RealDateCNFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss:SSS");
    private static SimpleDateFormat YearDateFormat1 = new SimpleDateFormat("yyyy");
    private static SimpleDateFormat YearDateFormat2 = new SimpleDateFormat("yyyy");
    private static SimpleDateFormat MonthDateFormat1 = new SimpleDateFormat("yyyy-MM");
    private static SimpleDateFormat TimeFormat = new SimpleDateFormat("HH:mm:ss");
    private static SimpleDateFormat TimeFormat1 = new SimpleDateFormat("HHmmss");
    private static SimpleDateFormat TimeFormat2 = new SimpleDateFormat("HH-mm-ss");
    private static SimpleDateFormat TimeSerialFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
    private static SimpleDateFormat JsonDateFormat1 = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    public static final int TIME_DATE = 0;
    public static final int TIME_DATETIME = 1;
    public static final int TIME_MONTH = 2;
    public static final int TIME_YEAR = 3;

    public static void Init() {
    }

    public static String toShortDateText(Date date) {
        synchronized (ShortDateFormat) {
            if (date == null) {
                return "";
            }
            return ShortDateFormat.format(date);
        }
    }

    public static String toShortDateText1(Date date) {
        synchronized (ShortDateFormat1) {
            if (date == null) {
                return "";
            }
            return ShortDateFormat1.format(date);
        }
    }

    public static String toShortDateText2(Date date) {
        synchronized (ShortDateFormat2) {
            if (date == null) {
                return "";
            }
            return ShortDateFormat2.format(date);
        }
    }

    public static String toNormalDateText(Date date) {
        synchronized (NormalDateFormat) {
            if (date == null) {
                return "";
            }
            return NormalDateFormat.format(date);
        }
    }

    public static String toNormalDateText1(Date date) {
        synchronized (NormalDateFormat1) {
            if (date == null) {
                return "";
            }
            return NormalDateFormat1.format(date);
        }
    }

    public static String toLongDateText(Date date) {
        synchronized (LongDateTimeFormat) {
            if (date == null) {
                return "";
            }
            return LongDateTimeFormat.format(date);
        }
    }

    public static String toRealDateText(Date date) {
        synchronized (RealDateTimeFormat) {
            if (date == null) {
                return "";
            }
            return RealDateTimeFormat.format(date);
        }
    }

    public static String toShortCNDateText(Date date) {
        synchronized (ShortDateCNFormat) {
            if (date == null) {
                return "";
            }
            return ShortDateCNFormat.format(date);
        }
    }

    public static String toShortCNDateText1(Date date) {
        synchronized (ShortDateFormatCN1) {
            if (date == null) {
                return "";
            }
            return ShortDateFormatCN1.format(date);
        }
    }

    public static String toTimeDateText(Date date) {
        synchronized (TimeFormat) {
            if (date == null) {
                return "";
            }
            return TimeFormat.format(date);
        }
    }

    public static String toTimeDateText1(Date date) {
        synchronized (TimeFormat1) {
            if (date == null) {
                return "";
            }
            return TimeFormat1.format(date);
        }
    }

    public static String toTimeDateText2(Date date) {
        synchronized (TimeFormat2) {
            if (date == null) {
                return "";
            }
            return TimeFormat2.format(date);
        }
    }

    public static String toNormalCNDateText(Date date) {
        synchronized (NormalDateCNFormat) {
            if (date == null) {
                return "";
            }
            return NormalDateCNFormat.format(date);
        }
    }

    public static String toLongCNDateText(Date date) {
        synchronized (LongDateCNFormat) {
            if (date == null) {
                return "";
            }
            return LongDateCNFormat.format(date);
        }
    }

    public static String toRealCNDateText(Date date) {
        synchronized (LongDateCNFormat) {
            if (date == null) {
                return "";
            }
            return LongDateCNFormat.format(date);
        }
    }

    public static String toDateText(Date date) {
        synchronized (NormalDateFormat) {
            if (date == null) {
                return "";
            }
            return NormalDateFormat.format(date);
        }
    }

    public static String toTimeText(Date date) {
        synchronized (TimeFormat) {
            if (date == null) {
                return "";
            }
            return TimeFormat.format(date);
        }
    }

    public static String toText(Date date) {
        synchronized (LongDateTimeFormat) {
            if (date == null) {
                return "";
            }
            return LongDateTimeFormat.format(date);
        }
    }

    public static String toTimeSerial(Date date) {
        synchronized (TimeSerialFormat) {
            if (date == null) {
                return "";
            }
            return TimeSerialFormat.format(date);
        }
    }

    public static String toJsonDateFormat1(Date date) {
        synchronized (JsonDateFormat1) {
            if (date == null) {
                return "";
            }
            return JsonDateFormat1.format(date);
        }
    }

    public static String toYearDisp(Date date) {
        synchronized (YearDateFormat1) {
            if (date == null) {
                return "";
            }
            return YearDateFormat1.format(date);
        }
    }

    public static String toMonthDisp(Date date) {
        synchronized (MonthDateFormat1) {
            if (date == null) {
                return "";
            }
            return MonthDateFormat1.format(date);
        }
    }

    public static Date toDate(String sdate)
            throws ParseException {
        if (TextUnit.StringIsEmpty(sdate)) {
            return null;
        }
        if (sdate.length() == 4) {
            Date date = null;
            synchronized (YearDateFormat2) {
                date = YearDateFormat2.parse(sdate);
            }
            Calendar d = Calendar.getInstance();
            d.setTime(date);
            d.set(6, 1);
            return d.getTime();
        }
        int p = sdate.indexOf('-');
        if (p > 0) {
            if (sdate.length() == "yy-MM".length()) {
                synchronized (ShortDateFormat) {
                    return ShortDateFormat.parse(sdate + "-01");
                }
            }
            if (sdate.length() == "yyyy-MM".length()) {
                synchronized (NormalDateFormat) {
                    return NormalDateFormat.parse(sdate + "-01");
                }
            }
            if (sdate.length() <= "yy-MM-dd".length()) {
                if (p >= 4) {
                    synchronized (ShortDateFormat1) {
                        return ShortDateFormat1.parse(sdate);
                    }
                }
                synchronized (ShortDateFormat) {
                    return ShortDateFormat.parse(sdate);
                }
            }
            if (sdate.length() <= "yyyy-MM-dd".length()) {
                synchronized (NormalDateFormat) {
                    return NormalDateFormat.parse(sdate);
                }
            }
            if (sdate.length() <= "yyyy-MM-dd HH:mm".length()) {
                synchronized (NormalDateFormat1) {
                    return NormalDateFormat1.parse(sdate);
                }
            }
            if (sdate.length() <= "yyyy-MM-dd HH:mm:ss".length()) {
                synchronized (LongDateTimeFormat) {
                    return LongDateTimeFormat.parse(sdate);
                }
            }
            synchronized (RealDateTimeFormat) {
                return RealDateTimeFormat.parse(sdate);
            }
        }
        if (sdate.indexOf('年') > 0) {
            if (sdate.length() == "yyyy".length()) {
                Date date = null;
                synchronized (YearDateFormat1) {
                    date = YearDateFormat1.parse(sdate);
                }
                Calendar d = Calendar.getInstance();
                d.setTime(date);
                d.set(6, 1);
                return d.getTime();
            }
            if (sdate.length() == "yyyy-MM".length()) {
                Date date = null;
                synchronized (MonthDateFormat1) {
                    date = MonthDateFormat1.parse(sdate);
                }
                Calendar d = Calendar.getInstance();
                d.setTime(date);
                d.set(5, 1);
                return d.getTime();
            }
        }
        if (sdate.indexOf('日') > 0) {
            if (sdate.length() <= "yy年MM月dd日".length()) {
                synchronized (ShortDateFormatCN1) {
                    return ShortDateFormatCN1.parse(sdate);
                }
            }
            if (sdate.length() <= "yyyy年MM月dd日".length()) {
                synchronized (ShortDateCNFormat) {
                    return ShortDateCNFormat.parse(sdate);
                }
            }
            if (sdate.length() <= "yyyy年MM月dd日 HH:mm".length()) {
                synchronized (NormalDateCNFormat) {
                    return NormalDateCNFormat.parse(sdate);
                }
            }
            if (sdate.length() <= "yyyy年MM月dd日 HH:mm:ss".length()) {
                synchronized (LongDateCNFormat) {
                    return LongDateCNFormat.parse(sdate);
                }
            }
            synchronized (RealDateCNFormat) {
                return RealDateCNFormat.parse(sdate);
            }
        }
        if (sdate.length() == "yyMM".length()) {
            synchronized (TimeIdShortFormat) {
                return TimeIdShortFormat.parse(sdate + "01");
            }
        }
        if (sdate.length() == "yyMMdd".length()) {
            synchronized (TimeIdShortFormat) {
                return TimeIdShortFormat.parse(sdate);
            }
        }
        if (sdate.length() == "yyyyMMdd".length()) {
            synchronized (TimeIdFormat) {
                return TimeIdFormat.parse(sdate);
            }
        }
        return DateFormat.getDateInstance().parse(sdate);
    }

    public static Date toYear(Object year) {
        if (TextUnit.isEmptyValue(year)) {
            return null;
        }
        try {
            if ((year instanceof Date)) {
                return toYear((Date) year);
            }
            return toYear(toDate(TextUnit.ObjToString(year)));
        } catch (Exception localException) {
        }
        return null;
    }

    public static Date toYear(int year) {
        Calendar d = Calendar.getInstance();
        d.set(year, 0, 1, 0, 0, 0);
        return d.getTime();
    }

    public static Date toYear(Date date) {
        if (date == null) {
            return null;
        }
        Calendar d = Calendar.getInstance();
        d.setTime(date);
        int year = d.get(1);
        d.set(year, 0, 1, 0, 0, 0);
        return d.getTime();
    }

    public static Date toMonth(Object yearMonth) {
        if (TextUnit.isEmptyValue(yearMonth)) {
            return null;
        }
        try {
            if ((yearMonth instanceof Date)) {
                return toMonth((Date) yearMonth);
            }
            return toMonth(toDate(TextUnit.ObjToString(yearMonth)));
        } catch (Exception localException) {
        }
        return null;
    }

    public static Date toMonth(int yearMonth) {
        int year = yearMonth / 100;
        int month = yearMonth - yearMonth / 100 * 100;
        if (month > 0) {
            month--;
        }
        Calendar d = Calendar.getInstance();
        d.set(year, month, 1, 0, 0, 0);
        return d.getTime();
    }

    public static Date toMonth(Date date) {
        if (date == null) {
            return null;
        }
        Calendar d = Calendar.getInstance();
        d.setTime(date);
        int year = d.get(TIME_DATETIME);
        int month = d.get(2);
        d.set(year, month, 1, 0, 0, 0);
        return d.getTime();
    }

    public static Date toDay(Date date) {
        if (date == null) {
            return null;
        }
        Calendar d = Calendar.getInstance();
        d.setTime(date);
        int year = d.get(TIME_DATETIME);
        int month = d.get(2);
        int day = d.get(5);
        d.set(year, month, day, 0, 0, 0);
        return d.getTime();
    }

    public static Date toDayAndHourAndMinute(Date date) {
        if (date == null) {
            return null;
        }
        Calendar d = Calendar.getInstance();
        d.setTime(date);
        int year = d.get(1);
        int month = d.get(2);
        int day = d.get(5);
        int hh = d.get(11);
        int mm = d.get(12);
        d.set(year, month, day, hh, mm, 0);
        return d.getTime();
    }

    public static Date toDayAndHourAndMinuteAndSecond(Date date) {
        if (date == null) {
            return null;
        }
        Calendar d = Calendar.getInstance();
        d.setTime(date);
        int year = d.get(1);
        int month = d.get(2);
        int day = d.get(5);
        int hh = d.get(11);
        int mm = d.get(12);
        int ss = d.get(13);
        d.set(year, month, day, hh, mm, ss);
        return d.getTime();
    }

    public static int toTimeId(Date date) {
        if (date == null) {
            return 0;
        }
        synchronized (TimeIdFormat) {
            return Integer.parseInt(TimeIdFormat.format(date));
        }
    }

    public static int toHourId(Date date) {
        if (date == null) {
            return 0;
        }
        Calendar d = Calendar.getInstance();
        d.setTime(date);
        return d.get(11);
    }

    public static int toTodId(Date date, int space) {
        if (date == null) {
            return 0;
        }
        Calendar d = Calendar.getInstance();
        d.setTime(date);
        int hour = d.get(11);
        int minute = d.get(12);
        return hour * 100 + minute / space * space / 5 * 5;
    }

    public static int toBirthDay(Date date) {
        if (date == null) {
            return 0;
        }
        Calendar d = Calendar.getInstance();
        d.setTime(date);
        int month = d.get(2);
        int day = d.get(5);
        return month * 100 + day;
    }

    public static String dateToDisplay(int timemode, Date date) {
        if (date == null) {
            return "";
        }
        switch (timemode) {
            case 3:
                return toYearDisp(date);
            case 2:
                return toMonthDisp(date);
            case 0:
                return toNormalDateText(date);
        }
        return toLongCNDateText(date);
    }

    public static Date timeIdToDate(int timeId) {
        int year = timeId / 10000;
        int month = timeId / 100 - year * 100;
        int day = timeId - year * 10000 - month * 100;

        Calendar d = Calendar.getInstance();
        d.set(year, Math.max(month - 1, 0), day, 0, 0, 1);
        return d.getTime();
    }

    public static String timeIdToDisplay(int timemode, Integer timeId) {
        if (timeId == null) {
            return null;
        }
        return timeIdToDisplay(timemode, timeId.intValue());
    }

    public static String timeIdToDisplay(int timemode, int timeId) {
        int year = 0;
        switch (timemode) {
            case 3:
                year = timeId / 10000;
                return Integer.toString(year);
            case 2:
                year = timeId / 10000;
                int month = timeId / 100 - year * 100;
                return Integer.toString(year) + "-" + Integer.toString(month);
        }
        year = timeId / 10000;
        int month = timeId / 100 - year * 100;
        int day = timeId - year * 10000 - month * 100;
        return Integer.toString(year) + "-" + Integer.toString(month) + "-" + Integer.toString(day);
    }

    public static boolean equalsDate(int timemode, Object m1, Object m2) {
        if (m1 == null) {
            return m2 == null;
        }
        if (m2 == null) {
            return false;
        }
        if (!(m1 instanceof Date)) {
            return false;
        }
        if (!(m2 instanceof Date)) {
            return false;
        }
        Calendar d1 = null;
        Calendar d2 = null;
        int year1 = 0;
        int year2 = 0;
        int month1 = 0;
        int month2 = 0;
        int day1 = 0;
        int day2 = 0;
        switch (timemode) {
            case 3:
                d1 = Calendar.getInstance();
                d1.setTime((Date) m1);
                year1 = d1.get(TIME_DATETIME);
                d2 = Calendar.getInstance();
                d2.setTime((Date) m2);
                year2 = d2.get(TIME_DATETIME);
                return year1 == year2;
            case 2:
                d1 = Calendar.getInstance();
                d1.setTime((Date) m1);
                year1 = d1.get(1);
                month1 = d1.get(2);
                d2 = Calendar.getInstance();
                d2.setTime((Date) m2);
                year2 = d2.get(1);
                month2 = d2.get(2);
                return (year1 == year2) && (month1 == month2);
            case 0:
                d1 = Calendar.getInstance();
                d1.setTime((Date) m1);
                year1 = d1.get(1);
                month1 = d1.get(2);
                day1 = d1.get(6);
                d2 = Calendar.getInstance();
                d2.setTime((Date) m2);
                year2 = d2.get(1);
                month2 = d2.get(2);
                day2 = d2.get(6);
                return (year1 == year2) && (month1 == month2) && (day1 == day2);
        }
        return ((Date) m1).getTime() == ((Date) m2).getTime();
    }

    public static Date formatDate(int timemode, Date date) {
        if (date == null) {
            return null;
        }
        switch (timemode) {
            case 3:
                return toYear(date);
            case 2:
                return toMonth(date);
            case 0:
                return toDay(date);
        }
        return toDayAndHourAndMinuteAndSecond(date);
    }

    public static int calcAge(Date sysdate, Date birthDay) {
        if (sysdate == null) {
            return 0;
        }
        if (birthDay == null) {
            return 0;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(sysdate);
        if (cal.before(birthDay)) {
            return 0;
        }
        int yearNow = cal.get(1);
        int monthNow = cal.get(2) + 1;
        int dayOfMonthNow = cal.get(5);

        cal.setTime(birthDay);
        int yearBirth = cal.get(1);
        int monthBirth = cal.get(2);
        int dayOfMonthBirth = cal.get(5);

        int age = yearNow - yearBirth;
        if (monthNow <= monthBirth) {
            if (monthNow == monthBirth) {
                if (dayOfMonthNow < dayOfMonthBirth) {
                    age--;
                }
            } else {
                age--;
            }
        }
        return age;
    }

    public static String calcTimeConsuming(int time) {
        StringBuffer buf = new StringBuffer();
        if (time < 0) {
            buf.append("- ");
            time = Math.abs(time);
        }
        int hour = time / 3600;
        if (hour < 10) {
            buf.append("0");
        }
        buf.append(Integer.toString(hour));
        buf.append(":");
        int minute = (time - hour * 3600) / 60;
        if (minute < 10) {
            buf.append("0");
        }
        buf.append(Integer.toString(minute));
        buf.append(":");
        int second = time - hour * 3600 - minute * 60;
        if (second < 10) {
            buf.append("0");
        }
        buf.append(Integer.toString(second));
        return buf.toString();
    }

    public static String calcTimeConsumingAsCn(long timemil) {
        StringBuffer buf = new StringBuffer();
        int time = (int) (timemil / 1000L);
        if (time < 0) {
            buf.append("- ");
            time = Math.abs(time);
        }
        int hour = time / 3600;
        if (hour > 0) {
            buf.append(Integer.toString(hour));
            buf.append("小时");
        }
        int minute = (time - hour * 3600) / 60;
        if (minute > 0) {
            buf.append(Integer.toString(minute));
            buf.append("分");
        }
        int second = time - hour * 3600 - minute * 60;
        if (second > 0) {
            buf.append(Integer.toString(second));
            buf.append("秒");
        }
        int ms = (int) (timemil - time * 1000);
        if (ms > 0) {
            buf.append(Integer.toString(ms));
            buf.append("毫秒");
        }
        return buf.toString();
    }
}
